home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 1.iso
/
ARGONET
/
PD
/
SOUND
/
REPLAYER.SPK
/
c
/
replayer
< prev
Wrap
Text File
|
1998-09-02
|
4KB
|
146 lines
/* replayer.c
Replayer -- audio player
Copyright (c) 1997 Mark Seaborn <mseaborn@argonet.co.uk>
This source file contains miscellaneous functions for Replayer: the
functions to create and destroy Replayer objects.
*/
#include <stdlib.h>
#include <string.h>
#include "replayer.h"
/* Initialisation methods for the whole module */
#ifndef replayer_NO_ATEXIT_HANDLER
/* Used to keep a list of all Replayer file objects. */
typedef struct object_list_node object_list_node;
struct object_list_node {
replayer_file *obj;
object_list_node *next;
};
static int initialised = 0;
static object_list_node *objects = 0;
static void replayer_initialise(void);
static void replayer_atexit(void);
/* To initialise, this registers an atexit handler. */
static void replayer_initialise(void)
{
if(initialised) return;
atexit(replayer_atexit);
initialised = 1;
}
/* At exit, this call replayer_sound_tidy() for each Replayer object. We
can't delete them, because that isn't our responsibility, and other bits
of code might try this as well. This is just an emergency measure. */
static void replayer_atexit(void)
{
object_list_node *c;
for(c=objects; c; c=c->next) replayer_sound_tidy(c->obj);
}
#endif /* replayer_NO_ATEXIT_HANDLER */
/* Object initialisation methods */
/* Creates a Replay object, given a Replay file. Returns zero if it
fails. */
replayer_file *replayer_create_file(const char *filename)
{
/* Create the object. */
/* Fail if a null pointer filename is passed. */
replayer_file *obj;
if(!filename) return 0;
obj = malloc(sizeof(replayer_file));
if(!obj) return 0;
/* Zero necessary fields. */
obj->header = 0;
obj->chunks = 0;
/* Playback preferences. */
obj->quality = 4; /* Max quality */
obj->skip_late_data = 0;
#ifndef replayer_NO_BACKWARDS
obj->backwards = 0;
#endif
/* Data for sound playing. */
obj->driver = 0;
obj->control = 0;
obj->buffer = 0;
obj->file = 0;
obj->playing = 0;
/* Copy the filename we are passed. */
obj->filename = malloc(strlen(filename) + 1);
if(!obj->filename) { free(obj); return 0; }
strcpy(obj->filename, filename);
/* Put this new object on the list of objects. */
#ifndef replayer_NO_ATEXIT_HANDLER
{
object_list_node *n = malloc(sizeof(object_list_node));
if(!n) { free(obj->filename); free(obj); return 0; }
n->obj = obj;
n->next = objects;
objects = n;
/* Make sure the atexit handler is registered. */
replayer_initialise();
}
#endif
/* And return the object. */
return obj;
}
/* Destroys a Replay object, freeing up all resources it used and stopped
sound playback. It won't do anything if you pass it a null pointer. */
void replayer_destroy(replayer_file *obj)
{
if(!obj) return;
/* Remove this object from the list. */
#ifndef replayer_NO_ATEXIT_HANDLER
{
object_list_node **c, *old;
for(c=&objects; *c; c=&(*c)->next) if((*c)->obj == obj) {
old = *c;
*c = old->next;
free(old);
break;
}
}
#endif
/* Tidy up after playback and stop playback if necessary. */
replayer_sound_tidy(obj);
/* Free everything, checking for null pointers. */
free(obj->filename);
/* Free the header, if it was loaded. */
if(obj->header) {
int i;
free(obj->header->title);
free(obj->header->date_and_copyright);
free(obj->header->other_details);
free(obj->header->video_type);
/* Free the soundtrack info. */
for(i=0; i<obj->header->no_soundtracks; ++i)
free(obj->header->soundtracks[i].type);
free(obj->header->soundtracks);
free(obj->header);
}
free(obj->chunks);
free(obj);
}